package references

import (
	"JVM/Jvmgo/GoToJVM/instructions/base"
	"JVM/Jvmgo/GoToJVM/runtimeData"
	"JVM/Jvmgo/GoToJVM/runtimeData/heap"
)

type CHECK_CAST struct {
	base.Index16Instruction
}

func (self *CHECK_CAST) Execute(frame *runtimeData.Frame) {
	stack := frame.OperandStack()
	ref := stack.PopRef()
	// 相较于instanceof，checkcast不会改变操作数栈，所以这里需要将弹出的ref重新压栈
	stack.PushRef(ref)
	if ref == nil {
		// null可以转化为任意类型
		return
	}

	cp := frame.Method().Class().ConstantPool()
	classRef := cp.GetConstant(self.Index).(*heap.ClassRef)
	class := classRef.ResolvedClass()
	if !ref.IsInstanceOf(class) {
		panic("java.lang.ClassCastException")
	}
}
